#include"mystdio.h"
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>

MyFILE* my_fopen(const char* filename,  const char* mode)
{
    //使用opend 根据打开模式来打开文件，以及填写myfile
    int fd = -1;
    if(strcmp(mode , "w")==0)
    {
        fd = open(filename , O_CREAT | O_WRONLY | O_TRUNC , UMASK);
    }
    else if(strcmp(mode , "r") == 0)
    {
        fd = open(filename , O_RDONLY);
    }
    else if(strcmp(mode , "a") == 0)
    {
        fd = open(filename , O_CREAT | O_WRONLY | O_APPEND , UMASK);
    }
    else if(strcmp(mode , "a+") == 0)
    {
        fd = open ( filename ,O_RDWR | O_CREAT | O_APPEND , UMASK );
    }
    else
    {}

    if(fd < 0) return NULL;
    //填写myfile结构体
    MyFILE* fp = (MyFILE*)malloc(sizeof(MyFILE));
    if(fp == NULL) return NULL;

    fp->fileno = fd;
    fp->flag = FLUSH_LINE;//默认行刷新

    fp->outbuffer[0] =0;
    fp->curr = 0;
    fp->cap = SIZE;

    return fp;
}

static void my_fflush_core(MyFILE* fp , int force)
{
    if(fp->curr==0) return;//没数据不刷新
    if(force == FORCE)
    {
        //强制刷新
        write(fp->fileno ,fp->outbuffer , fp->curr);
        fp->curr =0;
    }
    else
    {
        //根据刷新规则来看是否需要刷新
        if((fp->flag & FLUSH_LINE) && fp->outbuffer[fp->curr-1]=='\n')
        {
            //行刷新
            write(fp->fileno , fp->outbuffer , fp->curr);
            fp->curr =0;
        }
        else if((fp->flag & FLUSH_FULL) && fp->curr == fp->cap)
        {
            write(fp->fileno , fp->outbuffer , fp->curr);
            fp->curr =0;
        }
        else
        {}
    }
}

void my_fflush(MyFILE* fp)
{
   my_fflush_core(fp ,FORCE);
}

void my_fclose(MyFILE* fp)
{
    //关闭文件之前可以刷新缓冲区，且让os 也进行刷新
    if(fp->fileno > 0)
    {
        my_fflush(fp);
        fsync(fp->fileno);
        close(fp -> fileno);
        free(fp);
    }
}
int my_fwrite(const char* s , int size , MyFILE* fp)
{
    //本质是进行拷贝,将用户缓冲区中的数据拷贝放到语言级别的缓冲区当中
    memcpy(fp->outbuffer + fp->curr, s , size);
    fp->curr+=size;
    //判断是否需要刷新
    my_fflush_core(fp ,NORMAL);
    return size;
}
